<template>
  <section class="question" v-for="question in questions" :key="question.id">
    <template v-if="question.type == QUESTION_TYPE_DESCRIPTION">
      <p class="question__description">{{ question.title }}</p>
    </template>

    <template v-else>
      <QuestionHead :title="question.title" :description="question.description" :required="question.required" :seq="question.seq" />

      <div class="question__body">
        <template v-if="question.type == QUESTION_TYPE_SINGLE">
          <div v-for="option in question.options" :key="option.id" class="option" @click="selectSingle(question.id, option.id, option.text)">
            <input type="radio" :name="question.id" />
            <span class="option__radio"></span>
            <p class="option__pe">{{ option.text }}</p>
          </div>
        </template>

        <template v-else-if="question.type == QUESTION_TYPE_SELECT">
          <div class="question__body">
            <div class="select-box" @click="totalSelect($event)">
              <span class="select-box__icon"></span>
              <input class="select-box__input" type="text" placeholder="请选择" value="" readonly @blur="$event.currentTarget.parentNode.classList.remove('on')" />
              <ul class="select-box__list">
                <!-- 如果没有 stop, filter-input 的 @blur 和 selectBox 的 @click 都会触发 -->
                <li v-for="option in question.options" :key="option.id" class="select-box__list__li" @click.stop="select($event.currentTarget.parentNode.parentNode.getElementsByClassName('select-box__input')[0], question.id, option.id, option.text)">{{ option.text }}</li>
              </ul>
            </div>
          </div>
        </template>

        <template v-else-if="question.type == QUESTION_TYPE_MULTI">
          <div v-for="option in question.options" :key="option.id" class="option" @click="checkMulti(question.id, option.id, option.text)">
            <input type="checkbox" />
            <span class="option__checkbox" :class="true ? 'option__checkbox--check' : ''">
              <svg viewBox="0 0 11 9" fill-rule="evenodd" class="icon checkbox-icon tick"><path d="M1 3.544L4.29 7 10 1"></path></svg>
            </span>
            <p class="option__pe">{{ option.text }}</p>
          </div>
        </template>

        <template v-else-if="question.type == QUESTION_TYPE_TEXT">
          <input type="text" placeholder="请输入" @input="inputText(question.id, $event.currentTarget.value)" />
        </template>

        <template v-else-if="question.type == QUESTION_TYPE_TEXTAREA">
          <textarea @input="inputText(question.id, $event.currentTarget.value)" placeholder="请输入"></textarea>
        </template>

        <template v-else-if="question.type == QUESTION_TYPE_MATRIX_RADIO">
          <div class="matrix" v-for="subTitle in question.subTitles" :key="subTitle.id">
            <h3 class="matrix__subtitle">{{ subTitle.text }}</h3>
            <ul class="matrix__options">
              <li v-for="option in question.options" :key="option.id" class="matrix__options__li" @click="matrixCheck(question.id, subTitle.id, option.id, option.text)">
                <input type="radio" :name="subTitle.id" />
                <label :for="subTitle.id">{{ option.text }}</label>
              </li>
            </ul>
          </div>
        </template>
      </div>
    </template>
  </section>
</template>

<script>
import { QUESTION_TYPE_DESCRIPTION, QUESTION_TYPE_SINGLE, QUESTION_TYPE_MULTI, QUESTION_TYPE_SELECT, QUESTION_TYPE_TEXT, QUESTION_TYPE_TEXTAREA, QUESTION_TYPE_MATRIX_RADIO } from '@/constants/default.js'
import QuestionHead from './QuestionHead.vue'
import { findIndex } from '@/utils/utils'
import autoWidth from '@/utils/autoWidth'

export default {
  components: { QuestionHead },
  emits: {
    fill: () => true,
  },
  props: {
    questions: Array,
    collectTemplate: Array, // 收集用户填写的数据
  },
  data() {
    return {
      _collectTemplate: this.collectTemplate,
      QUESTION_TYPE_DESCRIPTION,
      QUESTION_TYPE_SINGLE,
      QUESTION_TYPE_MULTI,
      QUESTION_TYPE_SELECT,
      QUESTION_TYPE_TEXT,
      QUESTION_TYPE_TEXTAREA,
      QUESTION_TYPE_MATRIX_RADIO,
    }
  },
  methods: {
    // TODO: 这几个处理选项的, 代码基本是一致的, 应该可以合为一体.
    selectSingle(questionId, optionId, optionText) {
      const _collectTemplate = JSON.parse(JSON.stringify(this.collectTemplate))
      for (const question of _collectTemplate) {
        if (question.id === questionId) {
          // NOTE: question.options 的值是和 default.js 中的对应的
          question.options = [{ id: optionId, text: optionText }]
          break
        }
      }
      this.$emit('fill', _collectTemplate)
    },
    select(inputTarget, questionId, optionId, optionText) {
      const _collectTemplate = JSON.parse(JSON.stringify(this.collectTemplate))
      for (const question of _collectTemplate) {
        if (question.id === questionId) {
          // NOTE: question.options 的值是和 default.js 中的对应的
          question.options = [{ id: optionId, text: optionText }]
          inputTarget.value = optionText
          break
        }
      }
      this.$emit('fill', _collectTemplate)
    },
    checkMulti(questionId, optionId, optionText) {
      const _collectTemplate = JSON.parse(JSON.stringify(this.collectTemplate))
      for (const question of _collectTemplate) {
        if (question.id === questionId) {
          // NOTE: question.options 的值是和 default.js 中的对应的
          const i = findIndex(question.options, option => option.id === optionId)
          if (i === -1) {
            question.options = [...question.options, { id: optionId, text: optionText }]
          } else {
            question.options.splice(i, 1)
          }
          break
        }
      }
      this.$emit('fill', _collectTemplate)
    },
    inputText(questionId, text) {
      const _collectTemplate = JSON.parse(JSON.stringify(this.collectTemplate))
      for (const question of _collectTemplate) {
        if (question.id === questionId) {
          question.text = text
          break
        }
      }
      this.$emit('fill', _collectTemplate)
    },
    matrixCheck(questionId, subTitleId, optionId, optionText) {
      const _collectTemplate = JSON.parse(JSON.stringify(this.collectTemplate))
      for (const question of _collectTemplate) {
        if (question.id === questionId) {
          for (const subTitle of question.groups) {
            if (subTitle.id === subTitleId) {
              subTitle.options = [{ id: optionId, text: optionText }]
            }
          }
          break
        }
      }
      this.$emit('fill', _collectTemplate)
    },

    // 点击展开下拉框
    totalSelect(e) {
      // TODO: 这里有 bug
      if (Object.values(e.currentTarget.classList).indexOf('on') != -1) e.currentTarget.classList.remove('on')
      else e.currentTarget.classList.add('on')
    },
  },
  mounted() {
    autoWidth()
  },
}
</script>

<style lang="scss" scoped>
@mixin inputHidden {
  position: absolute;
  z-index: 2;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  opacity: 0;
  cursor: pointer;
}

.question {
  margin-top: 45px;

  .question__description {
    color: #2378ff;
    font-weight: bold;
  }

  .question__body {
    padding-top: 15px;

    > .option {
      height: 36px;
      padding-left: 10px;
      margin-left: -10px;

      position: relative;
      display: flex;
      align-items: center;
      justify-content: flex-start;

      border-radius: 4px;
      transition: 0.1s;
      cursor: pointer;
      &:hover {
        background: #2378ff22;
        color: #2378ff;
        .options__radio {
          box-shadow: inset 0 0 0px 1px #00000044;
        }
      }

      input {
        @include inputHidden;
      }

      .option__radio {
        width: 16px;
        height: 16px;
        overflow: hidden;

        border: none;
        border-radius: 100%;
        box-shadow: inset 0 0 0px 1px #00000044;

        transition: 0.3s;
        cursor: inherit;
      }
      input:checked + .option__radio {
        box-shadow: inset 0 0 0px 4px #2378ff;
      }

      .option__checkbox {
        width: 16px;
        height: 16px;
        overflow: hidden;
        position: relative;

        border: none;
        border-radius: 4px;
        box-shadow: inset 0 0 0px 1px #00000044;

        transition: 0.3s;
        cursor: inherit;
        svg {
          position: absolute;
          left: 50%;
          top: 50%;
          transform: translate(-50%, -50%);
          fill: none;
          stroke-width: 2px;
          width: 11px;
          height: 9px;
          stroke-dasharray: 16, 16;
          stroke-dashoffset: 16;
          transition: all 0.2s;
          stroke: #fff;
        }
      }
      input:checked + .option__checkbox {
        box-shadow: inset 0 0 0px 8px #2378ff;
        svg {
          stroke-dashoffset: 0;
        }
      }

      .option__pe {
        margin-left: 10px;
        display: block;
        cursor: inherit;
      }
    }
    > .select-box {
      position: relative;
      z-index: 99; /* 如果不高过下面的，会导致点击下拉选项时无效 */
      display: inline-block;
      margin-top: 9px;
      min-width: 218px;
      height: 40px;
      line-height: 40px;
      box-sizing: border-box;
      border: 1px solid #cbd5de;
      border-radius: 3px;
      cursor: pointer;
      transition: all 0.2s;
      user-select: none;
      -webkit-tap-highlight-color: transparent;
      .select-box__input {
        width: 100%;
        height: 38px;
        padding-left: 20px;
        padding-right: 34px;

        display: block;
        box-sizing: border-box;
        position: relative;

        background: none;
        overflow: visible;
        outline: none;
        border: none;
        cursor: pointer;
      }
      .select-box__list {
        position: absolute;
        top: 39px;
        left: -1px;
        width: 100%;
        max-height: 170px;
        overflow: auto;
        background: #fff;
        border: 1px solid #cbd5de;
        box-shadow: 0 10px 20px 0 rgb(0 0 0 / 10%);
        border-radius: 3px;
        transition: all 0.4s;
        transform: translateY(10px);
        opacity: 0;
        visibility: hidden;

        .select-box__list__li {
          position: relative;
          padding-left: 20px;
          padding-right: 34px;
          line-height: 52px;
          box-shadow: 0 0 1px 0px #00000022;
          &:hover {
            background-color: rgba(35, 120, 255, 0.1);
            color: rgba(35, 120, 255, 1);
          }
        }
      }
      .select-box__icon {
        position: absolute;
        right: 12px;
        top: 17px;
        width: 0;
        height: 0;
        border-top: 7px solid #bbbdbe;
        border-left: 5px solid transparent;
        border-right: 5px solid transparent;
        transform-origin: 50% 25%;
        transition: all 0.2s;
      }

      &.on .select-box__list {
        visibility: visible;
        transform: translateY(0);
        opacity: 1;
      }
      &.on .select-box__icon {
        transform: rotate(-180deg);
      }
    }

    > .matrix {
      margin-bottom: 25px;
      .matrix__subtitle {
        margin-bottom: 11px;
        font-weight: normal;
        font-size: 16px;
      }
      .matrix__options {
        display: flex;
        flex-wrap: wrap;

        .matrix__options__li {
          flex: 0 0 auto;

          width: 20%;
          padding: 2px;

          box-sizing: border-box;
          text-align: center;
          position: relative;
          input[type='radio'] {
            @include inputHidden;
          }
          label {
            width: 100%;
            height: 100%;
            min-height: 50px;
            padding: 5px;

            position: relative;
            display: flex;
            align-items: center;
            justify-content: center;

            background-color: #f4f4f4;
            border-radius: 4px;
            box-sizing: border-box;
          }
          input[type='radio']:checked + label {
            color: #fff;
            background-color: #2378ff;
            animation: click 0.2s ease;
          }
        }
        @keyframes click {
          0%,
          100% {
            transform: scale(1);
          }
          50% {
            transform: scale(0.92);
          }
        }
      }
    }

    > input,
    > textarea {
      width: 100%;
      height: 40px;
      margin-top: 9px;
      padding: 2px 20px;

      font-size: 16px;
      border-radius: 4px;
      border: 1px solid #cccccc;
      outline: none;
      &::placeholder {
        color: #aaa;
      }
      &:focus {
        border-color: #2378ff;
      }
    }
    > textarea {
      padding: 8px 20px;
      height: 120px;
      resize: none;
    }
  }
}
</style>
